package gotask

import (
	"github.com/google/uuid"
	log "github.com/sirupsen/logrus"
	"time"
)

type ArgsMap map[string]interface{}
type status string

const (
	CREATED = "created"
	ACQUIRED = "acquired"
	ENQUEUED = "enqeued"
	RUNNING = "running"
	FAILED = "failed"
	SUCESSED = "sucessed"
	FINISHED = "finished"

)

func (s status) String() string {
	switch s {
	case CREATED:
		return "created"
	case ACQUIRED:
		return "acquired"
	case ENQUEUED:
		return "enqueued"
	case RUNNING:
		return "running"
	case FAILED:
		return "failed"
	case SUCESSED:
		return "sucess"
	case FINISHED:
		return "finished"
	default:
		return "unknown"
	}
}

// StructToArgsMap Convert struct to ArgsMap, e.g. am := StructToArgsMap(yourStruct)
func StructToArgsMap(v interface{}) ArgsMap {
	v_bytes, err := json.Marshal(v)
	if err != nil {
		log.WithError(err).Errorf("failed to convert %+v to ArgsMap.", v)
	}
	argsMap := ArgsMap{}
	err = json.Unmarshal(v_bytes, &argsMap)
	if err != nil {
		log.WithError(err).Errorf("failed to convert %+v to ArgsMap.", v)
	}
	return argsMap
}

// MapToArgsMap Convert golang map to ArgsMap, e.g. am := MapToArgsMap(yourStruct)
func MapToArgsMap(v interface{}) ArgsMap {
	return StructToArgsMap(v)
}

// ArgsMapToStruct Convert ArgsMap to struct, e.g. err := ArgsMapToStruct(am, &yourStruct)
func ArgsMapToStruct(am ArgsMap, s interface{}) error {
	v_bytes, err := json.Marshal(am)
	if err != nil {
		return err
	}

	return json.Unmarshal(v_bytes, s)
}

type Task struct {
	ID                  string    `json:"task_id"` //任务ID
	CreatedAt           time.Time `json:"created_at"` // 创建任务的时间
	UpdatedAt           time.Time `json:"updated_at"` // 最近一次更新任务的时间
	QueueName           string    `json:"queue_name"` // 任务队列的名字
	JobName             string    `json:"job_name"`   // 任务的名称
	ResultArgsMap             ArgsMap   `json:"result_args_map"`  // 任务执行结果的map
	CurrentHandlerIndex int       `json:"current_handler_index"` // 当前任务所在task执行队列的索引id
	OriginalArgsMap     ArgsMap   `json:"original_args_map"`    //  从消息队列请求的参数map
	ResultLog           string    `json:"result_log"`           // 返回的
	Status				status    `json:"status"`             // 任务的当前状态
	Errlog				string	  `json:"err_log"`            //任务的错误结果日志
}

func NewTask(queueName, jobName string, originalArgsMap ArgsMap) *Task {
	u, _ := uuid.NewUUID()
	now := time.Now()

	task := &Task{u.String(),
		now,
		now,
		queueName,
		jobName,
		nil,
		0,
		originalArgsMap,
		"",
		CREATED,
		"",}

	return task
}
